package com.zdkj.subway.st.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.core.constant.SecurityConstants;
import com.zdkj.common.core.exceltools.ExcelUtil;
import com.zdkj.common.core.exceltools.IExcelExport;
import com.zdkj.common.core.exceltools.IExcelParser;
import com.zdkj.common.core.exceltools.MultipartFileToFile;
import com.zdkj.common.core.util.R;
import com.zdkj.common.core.util.SpringContextHolder;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.annotation.Inner;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.st.dto.in.SwStInputPassengerWorkTicketDTO;
import com.zdkj.subway.st.entity.SwStInputPassengerWorkTicket;
import com.zdkj.subway.st.entity.SwStInvalidTicket;
import com.zdkj.subway.st.entity.SwStInvalidTicketProduce;
import com.zdkj.subway.st.entity.SwStReportErrorAlterApply;
import com.zdkj.subway.st.fegin.SubwayStmService;
import com.zdkj.subway.st.mapper.SwStReportErrorAlterAppayMapper;
import com.zdkj.subway.st.service.SwStInputPassengerWorkTicketService;
import com.zdkj.subway.st.service.SwStInvalidTicketProduceService;
import com.zdkj.subway.st.service.SwStInvalidTicketService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * @ProjectName: zdkj
 * @Package: com.zdkj.subway.st.controller
 * @ClassName: SwStInvalidTicketController
 * @Description:
 * @Author: kangjian
 * @CreateDate: 2020/1/7 11:31
 * @Version: 1.0
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/swStInvalidTicket")
@Api(value = "swStInvalidTicket", tags = "无效票管理")
public class SwStInvalidTicketController {
    //下发状态  已下发1
    private static final String SEND_ON="1";

    //提交状态  已提交1 已回馈2
    private static final String SUBMIT_ON="1";
    private static final String SUBMIT_BACK="2";


    private final SwStInvalidTicketService swStInvalidTicketService;
    //无效生成申请
    private final SwStInvalidTicketProduceService swStInvalidTicketProduceService;

    private final SubwayStmService subwayStmService;
    private final SwStInputPassengerWorkTicketService swStInputPassengerWorkTicketService;
    @Resource
    SwStReportErrorAlterAppayMapper swStReportErrorAlterAppayMapper;

    @GetMapping("/{id}")
    public R getById(@PathVariable String id) {
        return R.ok(swStInvalidTicketService.getById(id));
    }

    @GetMapping("/page")
    public R<IPage> getDictPage(Page page, SwStInvalidTicket swStInvalidTicket) {
        String oldCardOrder = swStInvalidTicket.getOldCardOrder();
        String newCardOrder = swStInvalidTicket.getNewCardOrder();
        swStInvalidTicket.setOldCardOrder(null);
        swStInvalidTicket.setNewCardOrder(null);
        List<String> dateConditionsq = swStInvalidTicket.getDates1();
        List<String> dateConditionly = swStInvalidTicket.getDates2();
        QueryWrapper queryWrapper = Wrappers.query(swStInvalidTicket);
        queryWrapper.orderByDesc("apply_time","receive_time");
        if (ObjectUtil.isNotEmpty(dateConditionsq) && !"".equals(dateConditionsq.get(0))) {
            queryWrapper.between("date_format(apply_time,'%Y-%m-%d')", dateConditionsq.get(0), dateConditionsq.get(1));
        }
        if (ObjectUtil.isNotEmpty(dateConditionly) && !"".equals(dateConditionly.get(0))) {
            queryWrapper.between("date_format(receive_time,'%Y-%m-%d')", dateConditionly.get(0), dateConditionly.get(1));
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(oldCardOrder)) {
            queryWrapper.like("OLD_CARD_ORDER",oldCardOrder);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(newCardOrder)) {
            queryWrapper.like("NEW_CARD_ORDER",newCardOrder);
        }
        return R.ok(swStInvalidTicketService.page(page, queryWrapper));
    }

    @SysLog("无效票管理保存信息")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_add')")
    public R save(@Valid @RequestBody SwStInvalidTicket swStInvalidTicket) {
        PigxUser user = SecurityUtils.getUser();
        swStInvalidTicket.setDataSource("1");
        swStInvalidTicket.setCreatorName(user.getNikeName());
        swStInvalidTicket.setCreatorId(user.getId());
        swStInvalidTicket.setDeptId(user.getDeptId());
        //未提交
        swStInvalidTicket.setCheckStatus("0");
        swStInvalidTicket.setSendStatus("0");
        swStInvalidTicket.setConfirmStatus("0");
        swStInvalidTicket.setInputStatus("0");
        swStInvalidTicket.setOutputStatus("0");
        return R.ok(swStInvalidTicketService.save(swStInvalidTicket));
    }

    @PostMapping("/inner")
    @Inner
    public R feignSave(@Valid @RequestBody List<SwStInvalidTicket> swStInvalidTicket) {
        List<SwStInvalidTicket> saveList = new ArrayList<>();
        List<SwStInvalidTicket> updateList = new ArrayList<>();
        //如果存在更新，不存在insert
        for (SwStInvalidTicket stInvalidTicket : swStInvalidTicket) {
            SwStInvalidTicket serviceOne = swStInvalidTicketService.getOne(Wrappers.<SwStInvalidTicket>lambdaQuery()
                    .eq(SwStInvalidTicket::getStationLine, stInvalidTicket.getStationLine())
                    .eq(SwStInvalidTicket::getStationCode, stInvalidTicket.getStationCode())
                    .eq(SwStInvalidTicket::getOldCardOrder, stInvalidTicket.getOldCardOrder())
                    .eq(SwStInvalidTicket::getDelFlag, "0"));
            if(ObjectUtil.isNotEmpty(serviceOne)){
                stInvalidTicket.setId(serviceOne.getId());
                updateList.add(stInvalidTicket);
            }else {
                saveList.add(stInvalidTicket);
            }
        }
        if(CollectionUtils.isNotEmpty(updateList)){
            swStInvalidTicketService.updateBatchById(updateList);
        }
        if(CollectionUtils.isNotEmpty(saveList)){
            swStInvalidTicketService.saveBatch(saveList);
        }
        return R.ok();
    }



    @SysLog("批量删除无效票管理信息")
    @DeleteMapping("/delBatch")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_deletes')")
    public R removeByIds(@RequestBody List<Integer> ids) {
        return R.ok(swStInvalidTicketService.removeByIds(ids));
    }


    @SysLog("删除无效票管理信息")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_delete')")
    public R removeById(@PathVariable String id) {
        return R.ok(swStInvalidTicketService.removeById(id));
    }


    @PutMapping("/checkComplete")
    @SysLog("审批完成同步无效票")
    public R checkComplete(@Valid @RequestBody SwStInvalidTicket swStInvalidTicket) {
        PigxUser user = SecurityUtils.getUser();
        SwStInvalidTicketProduce swStInvalidTicketProduce=new SwStInvalidTicketProduce();
        swStInvalidTicketProduce.setTicketName(swStInvalidTicket.getTicketName());
        swStInvalidTicketProduce.setTicketSource("同步无效票");
        swStInvalidTicketProduce.setActiveTime(swStInvalidTicket.getActiveTime());
        swStInvalidTicketProduce.setDataSource("1");
        swStInvalidTicketProduce.setIsProduce("1");
        swStInvalidTicketProduce.setOldCardOrder(swStInvalidTicket.getOldCardOrder());
        swStInvalidTicketProduce.setStationCode(swStInvalidTicket.getStationCode());
        swStInvalidTicketProduce.setStationLine(swStInvalidTicket.getStationLine());
        swStInvalidTicketProduce.setTicketType(swStInvalidTicket.getTicketType());
        swStInvalidTicketProduce.setTicketTimesRemain(swStInvalidTicket.getRemainTimes());
        swStInvalidTicketProduce.setRemark(swStInvalidTicket.getRemark());
        swStInvalidTicketProduce.setCardIssuerId(swStInvalidTicket.getCardIssuerId());
        swStInvalidTicketProduce.setCardIssuer(swStInvalidTicket.getCardIssuer());
        swStInvalidTicketProduce.setCreatorName(user.getNikeName());
        swStInvalidTicketProduce.setCreatorId(user.getId());
        swStInvalidTicketProduce.setDeptId(user.getDeptId());
        return R.ok(swStInvalidTicketProduceService.save(swStInvalidTicketProduce));
    }

    @PutMapping
    @SysLog("修改无效票管理信息")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_update')")
    public R updateById(@Valid @RequestBody SwStInvalidTicket swStInvalidTicket) {
        PigxUser user = SecurityUtils.getUser();
        swStInvalidTicket.setCreatorName(user.getNikeName());
        swStInvalidTicket.setCreatorId(user.getId());
        return R.ok(swStInvalidTicketService.updateById(swStInvalidTicket));
    }
    @PutMapping("/send")
    @SysLog("下发无效票管理信息")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_send')")
    public R sendByIds(@RequestBody List<SwStInvalidTicket> ids) {
        ids.stream().forEach(s->s.setSendStatus(SEND_ON));
        swStInvalidTicketService.updateBatchById(ids);
        //同步修改审核 状态为已回馈
        ids.stream().forEach(s->s.setCheckStatus(SUBMIT_BACK));
        return R.ok();
    }

    @PutMapping("/submit")
    @SysLog("提交无效票管理信息")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_submit')")
    public R submitByIds(@RequestBody List<SwStInvalidTicket> ids) {
        ids.stream().forEach(s->s.setCheckStatus(SUBMIT_ON));
        boolean b = swStInvalidTicketService.updateBatchById(ids);
        ArrayList<SwStInvalidTicketProduce> list = new ArrayList<>();
        if(b){
            ids.forEach(item -> {
                SwStInvalidTicket swStInvalidTicket = swStInvalidTicketService.getById(item);
                PigxUser user = SecurityUtils.getUser();
                SwStInvalidTicketProduce swStInvalidTicketProduce=new SwStInvalidTicketProduce();
                swStInvalidTicketProduce.setStationLine(swStInvalidTicket.getStationLine());
                swStInvalidTicketProduce.setStationCode(swStInvalidTicket.getStationCode());
                swStInvalidTicketProduce.setTicketType(swStInvalidTicket.getTicketType());
                swStInvalidTicketProduce.setTicketName(swStInvalidTicket.getTicketName());
                swStInvalidTicketProduce.setActiveTime(swStInvalidTicket.getActiveTime());//新发票卡有效期
                swStInvalidTicketProduce.setTicketTimesRemain(swStInvalidTicket.getTicketTimes());//新票卡次数
                swStInvalidTicketProduce.setApplyTime(swStInvalidTicket.getApplyTime());
                swStInvalidTicketProduce.setOldCardOrder(swStInvalidTicket.getOldCardOrder());
                swStInvalidTicketProduce.setCheckStatus(swStInvalidTicket.getCheckStatus());
                swStInvalidTicketProduce.setDataSource(swStInvalidTicket.getDataSource());
                swStInvalidTicketProduce.setRemark(swStInvalidTicket.getRemark());
                swStInvalidTicketProduce.setClassNumber(swStInvalidTicket.getClassNumber());//班次
                //swStInvalidTicketProduce.setCreatorName(user.getUsername());
                //swStInvalidTicketProduce.setCreatorId((long) user.getId());
                swStInvalidTicketProduce.setCardIssuerId(swStInvalidTicket.getCardIssuerId());
                swStInvalidTicketProduce.setCardIssuer(swStInvalidTicket.getCardIssuer());
                swStInvalidTicketProduce.setCreatorName(swStInvalidTicket.getCreatorName());
                swStInvalidTicketProduce.setCreatorId(swStInvalidTicket.getCreatorId());
                swStInvalidTicketProduce.setDeptId(swStInvalidTicket.getDeptId());
                list.add(swStInvalidTicketProduce);
            });
        }
        if(list.size()>0){
            swStInvalidTicketProduceService.saveBatch(list);
        }
        return R.ok();
    }

    @PutMapping("/inputDetailSubmit")
    @SysLog("加入车票入库")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_inputDetail')")
    public R inputDetailSubmit(@Valid @RequestBody List<Integer> ids) {
        return R.ok(swStInvalidTicketService.inputDetailSubmitBatch(ids));
    }

    @PutMapping("/outDetailSubmit")
    @SysLog("加入车票出库")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_outDetail')")
    public R outDetailSubmit(@Valid @RequestBody List<Integer> ids) {
        return R.ok(swStInvalidTicketService.outDetailSubmitBatch(ids));
    }

    @PostMapping(value = "/import")
    @SysLog("导入无效票管理信息")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_import')")
    public R importExcel(@RequestParam("file") MultipartFile file) {
        try {
            File efile= MultipartFileToFile.multipartFileToFile(file);
            Workbook workbook = ExcelUtil.chooseWorkbook(efile);
            Sheet sheet = workbook.getSheetAt(0);
            IExcelParser excelParser = SpringContextHolder.getBean("commonExcelParse");//设置头信息
            List<SwStInvalidTicket> list = excelParser.parse(sheet, new SwStInvalidTicket());
            swStInvalidTicketService.saveBatch(list);
            return R.ok("1","导入成功");
        } catch (Exception e) {
            log.error("",e);
            return R.failed("Excel导入失败！");
        }
    }

    @GetMapping("/export")
    @SysLog("导出无效票管理信息")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_export')")
    public void exportExcel(SwStInvalidTicket swStInvalidTicket, HttpServletResponse response) {
        List<SwStInvalidTicket> swStInvalidTicketlist = swStInvalidTicketService.list(Wrappers.query(swStInvalidTicket));
        IExcelExport excelExport = SpringContextHolder.getBean("commonExcelExport");
        Workbook workbook = excelExport.parse(swStInvalidTicketlist);
        try {
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 完善无效票信息
     * @param testId
     * @return
     */
    @ApiOperation(value = "完善无效票信息", notes = "完善无效票信息")
    @SysLog("完善无效票信息")
    @GetMapping("/test/{testId}")
    public R getByInvalidId(@PathVariable String testId) {
        return R.ok(swStInvalidTicketService.getById(testId));
    }


    /**
     * 修改完善无效票信息
     * @param swStInvalidTicket
     * @return
     */
    @PutMapping("/completeInval")
    @ApiOperation(value = "修改完善无效票信息", notes = "修改完善无效票信息")
    @SysLog("修改完善无效票信息")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_completeInval')")
    public R updateInvalidById(@Valid @RequestBody SwStInvalidTicket swStInvalidTicket) {
        PigxUser user = SecurityUtils.getUser();
        swStInvalidTicket.setCreatorName(user.getNikeName());
        swStInvalidTicket.setCreatorId(user.getId());
        boolean b = swStInvalidTicketService.updateById(swStInvalidTicket);
        if(b){
            SwStInputPassengerWorkTicketDTO inputPassengerWorkTicketDTO = new SwStInputPassengerWorkTicketDTO();
            inputPassengerWorkTicketDTO.setCardOrder(swStInvalidTicket.getOldCardOrder());
            inputPassengerWorkTicketDTO.setReplaceCardOrder(swStInvalidTicket.getNewCardOrder());
            inputPassengerWorkTicketDTO.setActiveTime(swStInvalidTicket.getActiveTime());
            inputPassengerWorkTicketDTO.setTicketTimes(swStInvalidTicket.getTicketTimes());
            subwayStmService.InputPassengerWorkTicketUpdate(
                    inputPassengerWorkTicketDTO,
                    SecurityConstants.FROM_IN
            );
        }
        return R.ok();
    }

    /**
     * 批量通知完善无效票信息
     * @param ids
     */
    @PutMapping("/inform")
    @ApiOperation(value = "批量通知完善无效票信息", notes = "批量通知完善无效票信息")
    @SysLog("批量通知完善无效票信息")
    @PreAuthorize("@pms.hasPermission('st_invalid_ticket_inform')")
    @Transactional(rollbackFor = Exception.class)
    public R informByIds(@RequestBody List<Integer> ids) {
        List<SwStInvalidTicket> invalidTicketsUpdate = new ArrayList<>();
        List<SwStInputPassengerWorkTicket> testConfirmList = new ArrayList<>();
        //根据ids查询要修改的无效票信息并改为已通知
        Collection<SwStInvalidTicket> invalidTicketsList = swStInvalidTicketService.listByIds(ids);
        if(CollectionUtils.isNotEmpty(invalidTicketsList)){
            for (SwStInvalidTicket swStInvalidTicket : invalidTicketsList) {
                swStInvalidTicket.setConfirmStatus("1");//已通知
                invalidTicketsUpdate.add(swStInvalidTicket);

                //如果新卡号存在 同步更新即时退换票
                if(StringUtils.isNotEmpty(swStInvalidTicket.getNewCardOrder()) && "0".equals(swStInvalidTicket.getDelFlag())){
                    LambdaQueryWrapper<SwStInputPassengerWorkTicket> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(SwStInputPassengerWorkTicket::getCardOrder, swStInvalidTicket.getOldCardOrder());//旧卡号
                    queryWrapper.eq(SwStInputPassengerWorkTicket::getOperationType, "1");//非即时退换票
                    queryWrapper.eq(SwStInputPassengerWorkTicket::getDelFlag,"0");
                    List<SwStInputPassengerWorkTicket> inputPassengerWorkTicketsList = swStInputPassengerWorkTicketService.list(queryWrapper);
                    if(CollectionUtils.isNotEmpty(inputPassengerWorkTicketsList) && inputPassengerWorkTicketsList.size() == 1){
                        SwStInputPassengerWorkTicket swStInputPassengerWorkTicket =
                                inputPassengerWorkTicketsList.get(0);
                        swStInputPassengerWorkTicket.setInvalidTicketConfirmStatus(CommonConstants.INWANSHAN);//已完善
                        testConfirmList.add(swStInputPassengerWorkTicket);
                    }else {
                        return R.failed("请检查车站数据信息，可能存在重复的新卡号或者没有匹配到新卡号！");
                    }
                }else {
                    return R.failed("请检查完善信息，未能找到要通知的新卡号！");
                }
            }
        }
        if(CollectionUtils.isNotEmpty(invalidTicketsUpdate) && CollectionUtils.isNotEmpty(testConfirmList)){
            swStInvalidTicketService.updateBatchById(invalidTicketsUpdate);//修改无效票通知状态
            swStInputPassengerWorkTicketService.updateBatchById(testConfirmList);//修改车站无效票已完善状态
            return R.ok();
        }else {
            return R.failed("通知失败，请检查数据！");
        }

    }


    /**
     * 修改无效票管理通知状态为已确认
     *
     * @param
     * @return R
     */
    @ApiOperation(value = "修改无效票管理通知状态", notes = "修改无效票管理通知状态")
    @PostMapping("/updateBatch")
    @Inner
    public R feignInvaildTicketUpdate(@Valid @RequestBody List<SwStInvalidTicket> invalidTicketList) {
        ArrayList<SwStInvalidTicket> arrayList = new ArrayList<>();
        invalidTicketList.forEach(item -> {
            QueryWrapper<SwStInvalidTicket> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(SwStInvalidTicket::getOldCardOrder,item.getOldCardOrder());
            wrapper.lambda().eq(SwStInvalidTicket::getDelFlag,"0");
            SwStInvalidTicket swStInvalidTicket = swStInvalidTicketService.getOne(wrapper);
            swStInvalidTicket.setConfirmStatus("2");//已确认
            arrayList.add(swStInvalidTicket);

        });
        if (arrayList.size()>0){
            return R.ok(swStInvalidTicketService.updateBatchById(arrayList));
        }
        return R.ok();
    }

    /**
     * 根据id查询要入库或出库或发送无效票到生产申请的数据
     * @param ids id
     * @return R
     */
    @ApiOperation(value = "根据id查询要入库或出库或发送无效票到生产申请的数据", notes = "根据id查询要入库或出库或发送无效票到生产申请的数据")
    @SysLog("根据id查询要入库或出库或发送无效票到生产申请的数据")
    @GetMapping("/queryIds")
    public R queryIds(@RequestParam("ids") String ids) {
        String[] split = ids.split(",");
        List<String> strings = Arrays.asList(split);
        Collection<SwStInvalidTicket> swStInvalidTickets = swStInvalidTicketService.listByIds(strings);
        if(CollectionUtil.isNotEmpty(swStInvalidTickets)){
            for (SwStInvalidTicket swStInvalidTicket : swStInvalidTickets) {
                LambdaQueryWrapper<SwStReportErrorAlterApply> queryWrapper = Wrappers.<SwStReportErrorAlterApply>lambdaQuery()
                    .eq(SwStReportErrorAlterApply::getCardNo, swStInvalidTicket.getOldCardOrder())
                    .eq(SwStReportErrorAlterApply::getDelFlag, "0")
                    .and(wrapper -> wrapper.in(SwStReportErrorAlterApply::getCheckStatus, '1','2')//审批状态1.已申请2.待审批3.审批通过4.审批不通过
                            .or(wrapper1 -> wrapper1.eq(SwStReportErrorAlterApply::getCheckStatus, "3").eq(SwStReportErrorAlterApply::getIsModify,"0"))//审批通过并且未修改
                            );
                List<SwStReportErrorAlterApply> errorAlterApplyList = swStReportErrorAlterAppayMapper.selectList(queryWrapper);
                if(CollectionUtil.isNotEmpty(errorAlterApplyList)){
                    return R.failed("原卡号为："+swStInvalidTicket.getOldCardOrder()+" 的数据在车站处于报表差错修改状态中,不能进行此操作！");
                }
            }

        }
        return R.ok();
    }
}

